package com.yellowpage.alarm.service;

import java.util.List;
import java.util.Map;
import com.yellowpage.white.common.PageRender;
import com.yellowpage.white.dao.QueryAssistantSQL;
import com.yellowpage.white.exception.AlarmException;
import com.yellowpage.white.service.BaseServiceImpl;
import com.yellowpage.white.util.ObjectUtil;
import com.yellowpage.alarm.data.AlarmInfo;
import com.yellowpage.alarm.data.AlarmInfoUser;
import com.yellowpage.alarm.dao.AlarmInfoDao;
import com.yellowpage.alarm.dao.AlarmInfoUserDao;

public class AlarmInfoServiceImpl extends BaseServiceImpl implements
		AlarmInfoService {
	/**
	 * 告警信息DAO接口
	 */
	private AlarmInfoDao alarmInfoDao;
	/**
	 * 告警信息处理人DAO接口
	 */
	private AlarmInfoUserDao alarmInfoUserDao;

	/**
	 * 告警信息通知工厂
	 */
	private AlarmInfoNotifyFactory notifyFactory;

	public AlarmInfoNotifyFactory getNotifyFactory() {
		return notifyFactory;
	}

	public void setNotifyFactory(AlarmInfoNotifyFactory notifyFactory) {
		this.notifyFactory = notifyFactory;
	}

	public AlarmInfoUserDao getAlarmInfoUserDao() {
		return alarmInfoUserDao;
	}

	public void setAlarmInfoUserDao(AlarmInfoUserDao alarmInfoUserDao) {
		this.alarmInfoUserDao = alarmInfoUserDao;
	}

	public void setAlarmInfoDao(AlarmInfoDao alarmInfoDao) {
		this.alarmInfoDao = alarmInfoDao;
	}

	/* White generate Method */
	public AlarmInfo getAlarmInfo(Long id) {
		return alarmInfoDao.get(id);
	}

	public List<AlarmInfo> getAllAlarmInfo() {
		return alarmInfoDao.getAll();
	}

	public List<Map> queryAlarmInfoByPage(Map queryMap, PageRender pageRender) {

		QueryAssistantSQL sqlAssistant = baseDao
				.newQueryAssistantSQL(
						"SELECT a.ALARM_TYPE, a.ALARM_LEVEL, a.INFORM_TYPE, to_char(a.CREATE_TIME,'yyyy-mm-dd hh24:mi:ss') as CREATE_TIME, "
								+ "to_char(a.CONFIRM_TIME,'yyyy-mm-dd hh24:mi:ss') as CONFIRM_TIME, to_char(a.REVOCER_TIME,'yyyy-mm-dd hh24:mi:ss') as REVOCER_TIME, "
								+ "a.REVOCER_DESC, a.CAUSE, a.ID, a.STATUS, a.THRESHOLD_TIMES, a.NOTIFY_TIMES, b.USER_ID,c.NAME  FROM CA_ALARMINFO a left join CA_USER c on a.LAST_UPDATE_USER=c.USER_ID left join CA_ALARMINFO_USER b on a.ALARM_TYPE=b.ALARM_TYPE and b.USER_ID="
								+ queryMap.get("userId") + " WHERE 1=1 ")
				.addCondition(" and a.ALARM_TYPE = :alarmType ")
				.addCondition(" and a.ALARM_LEVEL = :alarmLevel ")
				.addCondition(" and a.CAUSE like :cause ")
				.addCondition(" and a.STATUS = :status ");
		sqlAssistant.setTail("order by a.CREATE_TIME desc");
		List<Map> resultList = sqlAssistant.queryByPage(
				baseDao.getConnection(), queryMap, pageRender);

		return resultList;
	}

	public void saveAlarmInfo(AlarmInfo alarmInfo) {
		alarmInfoDao.save(alarmInfo);
	}

	public void updateAlarmInfo(AlarmInfo alarmInfo) {
		alarmInfoDao.update(alarmInfo);
	}

	public void delete(List deleteList) {
		alarmInfoDao.remove(deleteList);
	}

	@Override
	public List<AlarmInfo> getEffectiveAlarmInfos() {
		List<AlarmInfo> alarmInfos = null;
		alarmInfos = this.alarmInfoDao.getEffectiveAlarmInfos();
		return alarmInfos;
	}

	@Override
	public void alarm(AlarmInfo alarmInfo) throws AlarmException {
		// 必要条件检查
		if (null == alarmInfo || ObjectUtil.isNull(alarmInfo.getAlarmType())
				|| ObjectUtil.isNull(alarmInfo.getCause())
				|| ObjectUtil.isNull(alarmInfo.getInformType())) {
			String errorMessage = "缺少必要条件";
			log.error(errorMessage);
			throw new AlarmException(errorMessage);
		}
		// 告警类别
		String alarmType = alarmInfo.getAlarmType();
		// 告警原因
		String cause = alarmInfo.getCause();
		// 通知机制
		String informType = alarmInfo.getInformType();
		// 通知次数阈值
		Long thresholdTimes = alarmInfo.getThresholdTimes();
		// 已通知次数
		Long notifyTimes = alarmInfo.getNotifyTimes();

		if (notifyTimes >= thresholdTimes) {
			log.info("告警信息["+alarmInfo.getId()+"]已达到通知次数阈值，无需再通知。");
			return;
		}

		// 查询与告警类别关联的告警信息处理人集合
		List<AlarmInfoUser> alarmInfoUsers = this.getAlarmInfoUserDao()
				.getAlarmInfoUsersByAlarmType(alarmType);

		if (null == alarmInfoUsers || alarmInfoUsers.isEmpty()) {
			String errorMessage = "告警类别为[" + alarmType + "]的告警信息未配置关联处理人";
			log.info(errorMessage);
			throw new AlarmException(errorMessage);
		}

		AlarmInfoNotifyService notifyService = this.notifyFactory.notifyServiceMap
				.get(informType);
		if(null==notifyService)
		{
			String errorMessage="通知类别为["+informType+"]未匹配到相关的通知业务类";
			log.info(errorMessage);
			throw new AlarmException(errorMessage);
		}
		// 告警通知
		notifyService.notify(cause, alarmInfoUsers);

		alarmInfo.setNotifyTimes(notifyTimes + 1);
		try {
			this.alarmInfoDao.update(alarmInfo);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			throw new AlarmException("修改告警信息已通知次数失败，失败原因为[" + e.getMessage()
					+ "]", e);
		}

	}

}